iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
1
Modern Web

React 30天系列 第 16

Day 16-[番外]HOC簡易實例

  • 分享至 

  • xImage
  •  

前情提要:昨天了解了HOC的概念,但礙於手邊有的東西不好變化,也有可能是手邊的redux,對於一次結合覺得有點複雜,今天就用簡單的react application來實作HOC吧!

首先,我們的情境是...
頁面所需的資料userList透過api取得,每次做非同步處理的時候都需要等待response的時間,我希望user在等待時有loading畫面,而loading這塊使用HOC處理。

備註:這邊的練習沒有使用redux。

這邊建立一個App component透過api取得user資料,然後將userList資料和Loading狀態作為props送給UserList。
這邊為了避免不重要的fetch過程佔版面,所以只顯示部分程式碼。

// ...
return (
  <div>
    <UserList
      isLoading={this.state.isLoading}
      userList={this.state.userList} />
  </div>
);
// ...

在HOC這邊,還記得昨天提到的概念嗎?HOC就是一個component包著另一個component!(好饒舌啊!!!)
我把UserList component送來後,將props的內容拆成:isLoading和其餘props,
接著判斷props的isLoading狀態是否為true,若為ture顯示isLoading的gif圖片,若為false則顯示渲染被包裹的component(在這邊指UserList)。
如此一來當未來我有其他資料需要loading的時候就可以透過withLoading處理loading顯示。

import React from "react";

const withLoading = WrappedComponent => ({ isLoading, ...props }) => {
  return isLoading ? (
    <img
      src="https://loading.io/spinners/balls/lg.circle-slack-loading-icon.gif"
      alt="loading"
    />
  ) : (
    <WrappedComponent {...props} />
  );
};

export default withLoading;

而在UserList這邊,我只需要將寫好的withLoading匯入,並將UserList送進withLoading處理,就可以免除等待response期間無資料的空白期。

import React from "react";
import withLoading from "../hoc/with_loading";

const UserList = ({ userList }) => {
  return userList.map((user, index) => (
    <div key={index}>
      <img src={user.picture.thumbnail} alt="" />
      <ul style={{display: 'inline-block'}}>
        <li>name: {`${user.name.first} ${user.name.last}`}</li>
        <li>gender: {user.gender}</li>
        <li>email: {user.email}</li>
      </ul>
    </div>
  ));
};

export default withLoading(UserList);

測試畫面如下:
https://i.imgur.com/oOnlKDm.gif
完整程式碼請參考:github傳送門


今日總結:
HOC幫助我們把component與component之間類似的行爲抽出使用,覺得最困難的點是判斷哪些邏輯是共通的可以抽出使用,或許它也跟reduxㄧ樣,當我們需要HOC的時候,它自然就會出來向我們招手了。

參考資料:Handle loadings in React by using Higher Order Components


上一篇
Day 15-[番外]關於HOC
下一篇
Day 17-redux middleware(使用redux-promise處理非同步資料吧)
系列文
React 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言